package com.example.orderminiappapi.controller;

import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import com.example.orderminiappapi.bean.*;
import com.example.orderminiappapi.service.*;
import com.example.orderminiappapi.tool.Createuuid;
import com.example.orderminiappapi.tool.GetMode;
import com.example.orderminiappapi.tool.GetTime;
import com.example.orderminiappapi.utils.pythonSocket.PythonSocket;
import com.example.orderminiappapi.utils.webSocket.WebSocketServer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

@RestController
@CrossOrigin
public class ShopController {

    @Autowired
    private ShopService shopService;

    @Autowired
    private MealService mealService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private UserService userService;

    @Autowired
    private NoticeService noticeService;

    @Autowired
    private ScoreService scoreService;

    @Autowired
    private SearchService searchService;

    /**
     * 获取首页的推荐餐厅(需要推荐算法辅助)
     */
    @ResponseBody
    @RequestMapping(value = "/getShopList", method = RequestMethod.POST,produces = "application/json;charset=UTF-8")
    private Response getShopList(HttpServletRequest request, @RequestBody ShopSearchCondition shopSearchCondition) throws IOException {

        String token = request.getHeader("tokenMiniAPP");

        JWTVerifier build = JWT.require(Algorithm.HMAC256("userInfo")).build();
        DecodedJWT verify = build.verify(token);

        String userId = verify.getClaim("openId").asString();

        shopSearchCondition.setUserId(userId);
        ObjectMapper mapper = new ObjectMapper();

        PythonSocket pythonSocket = new PythonSocket();
        Object getOneRecommendList = pythonSocket.remoteCall(mapper.writeValueAsString(shopSearchCondition));

        RecommendShopList recommendShopList = mapper.readValue(getOneRecommendList.toString(), RecommendShopList.class);

        Response response = new Response("10000", "成功", recommendShopList.getRecommendList());
        return response;
    }


    /**
     * 获取搜寻页的推荐餐厅排行榜
     */
    @ResponseBody
    @RequestMapping(value = "/searchRecommendShop", method = RequestMethod.POST,produces = "application/json;charset=UTF-8")
    private Response searchRecommendShop() throws JsonProcessingException {
        List<Shop> shopList = shopService.searchRecommendShop();
        Response response = new Response("10000", "成功", shopList);
        return response;
    }

    /**
     * 根据关键词搜索商店列表
     */
    @ResponseBody
    @RequestMapping(value = "/searchShopByKeywords", method = RequestMethod.POST,produces = "application/json;charset=UTF-8")
    private Response searchShopByKeywords(HttpServletRequest request, @RequestBody Request requests) throws JsonProcessingException {
        String token = request.getHeader("tokenMiniAPP");

        JWTVerifier build = JWT.require(Algorithm.HMAC256("userInfo")).build();
        DecodedJWT verify = build.verify(token);

        String userId = verify.getClaim("openId").asString();

        Score score = new Score();
        score.setUserId(userId);

        Score flagScore = scoreService.getSearchScoreById(score);
        if(flagScore == null) {
            scoreService.insertSearchScore(score);
        }

        List<Shop> shopList = shopService.searchShopByKeywords(requests);

        List<String> backCateNameList = new ArrayList<>();
        for(int i = 0; i < shopList.size(); i++){
            backCateNameList.add(shopList.get(i).getBackCateName());
        }

        GetMode getMode = new GetMode();
        String mode = getMode.listGetMode(backCateNameList);

        score.setBackCateName(mode);
        scoreService.addSearchScore(score);

        Search search = new Search();
        search.setUserId(userId);
        search.setSearchKeywords(requests.getKeywords());

        Search search1 = searchService.getIfHasSearched(search);
        if(search1 == null) {
            Createuuid createuuid = new Createuuid();
            String uuid = createuuid.getOrderIdByUUId();
            search.setSearchId(uuid);

            GetTime getTime = new GetTime();
            String createTime = getTime.getNowTime();
            search.setSearchTime(createTime);

            searchService.addSearchItem(search);
        } else {
            GetTime getTime = new GetTime();
            String createTime = getTime.getNowTime();
            search1.setSearchTime(createTime);

            searchService.refreshSearchItem(search1);
        }

        Response response = new Response("10000", "成功", shopList);
        return response;
    }


    /**
     * 后台管理相关接口
     */

    /**
     * 根据ownerId获取其拥有的商店
     */
    @ResponseBody
    @RequestMapping(value = "/shopOwnerSearch", method = RequestMethod.POST,produces = "application/json;charset=UTF-8")
    private Response shopOwnerSearch(HttpServletRequest request) throws JsonProcessingException {

        String token = request.getHeader("tokenMiniAPP");

        JWTVerifier build = JWT.require(Algorithm.HMAC256("userInfo")).build();
        DecodedJWT verify = build.verify(token);

        String userId = verify.getClaim("userId").asString();

        Shop shop = new Shop();
        shop.setOwnerId(userId);

        List<Shop> shopList = shopService.shopOwnerSearch(shop);
        Response response = new Response("10000", "成功", shopList);
        return response;
    }

    /**
     * 获取所有的商店类型
     */
    @ResponseBody
    @RequestMapping(value = "/getAllBackCateName", method = RequestMethod.POST,produces = "application/json;charset=UTF-8")
    private Response getAllBackCateName() {
        Response response = new Response("10000", "成功", shopService.getAllBackCateName());
        return response;
    }

    /**
     * 根据shopId获取该商店的具体信息
     */
    @ResponseBody
    @RequestMapping(value = "/searchOneShop", method = RequestMethod.POST,produces = "application/json;charset=UTF-8")
    private Response searchOneShop(HttpServletRequest request) throws JsonProcessingException {

        String token = request.getHeader("tokenMiniAPP");

        JWTVerifier build = JWT.require(Algorithm.HMAC256("userInfo")).build();
        DecodedJWT verify = build.verify(token);

        String shopId = verify.getClaim("shopId").asString();

        Shop shop = new Shop();
        shop.setShopId(shopId);

        Response response = new Response("10000", "成功", shopService.searchOneShop(shop));
        return response;
    }

    /**
     * 修改商店的具体信息
     */
    @ResponseBody
    @RequestMapping(value = "/updateShopInfo", method = RequestMethod.POST,produces = "application/json;charset=UTF-8")
    private Response updateShopInfo(HttpServletRequest request, @RequestBody Shop shop) {

        String token = request.getHeader("tokenMiniAPP");

        JWTVerifier build = JWT.require(Algorithm.HMAC256("userInfo")).build();
        DecodedJWT verify = build.verify(token);

        String shopId = verify.getClaim("shopId").asString();

        shop.setShopId(shopId);

        shopService.updateShopInfo(shop);

        Response response = new Response("10000", "成功", "成功");
        return response;
    }

    /**
     * 商店首页的数字信息
     */
    @ResponseBody
    @RequestMapping(value = "/getShopNumInfo", method = RequestMethod.POST,produces = "application/json;charset=UTF-8")
    private Response getShopNumInfo(HttpServletRequest request) throws IOException {

        String token = request.getHeader("tokenMiniAPP");

        JWTVerifier build = JWT.require(Algorithm.HMAC256("userInfo")).build();
        DecodedJWT verify = build.verify(token);

        String userId = verify.getClaim("userId").asString();
        String shopId = verify.getClaim("shopId").asString();

        Shop shop = new Shop();
        shop.setOwnerId(userId);

        User user = new User();
        user.setUserId(userId);

        GetTime getTime = new GetTime();
        String[] parts = getTime.getNowTime().split("-", 3);
        String year = parts[0];
        String month = parts[1];

        String date = year + "-" + month;

        Order order = new Order();
        order.setCreateTime(date);
        order.setShopId(shopId);

        User user1 = userService.findShopOwner(user);

        HashMap map = new HashMap() {
            {
                put("shopNum", shopService.shopOwnerSearch(shop).size());
                put("shopExamineNum", shopService.shopOwnerSearchExamine(shop).size());
                put("mealNum", mealService.getAllShopMealsCount(shop));
                put("needHandleNum", orderService.getAllShopUnAcceptedOrder(shop));
                put("monthlyOrderNum", orderService.getAllOrderTrend(order, shop));
                put("monthlyOrderMoney", orderService.getAllOrderTrend(order, shop) == 0 ? 0 : orderService.getAllSaleTrend(order, shop));
                put("userName", user1.getUserName());
                put("userRole", user1.getUserRole());
            }
        };

        Response response = new Response("10000", "成功", map);

        return response;
    }

    /**
     * 申请新商店
     */
    @ResponseBody
    @RequestMapping(value = "/applyNewShop", method = RequestMethod.POST,produces = "application/json;charset=UTF-8")
    private Response applyNewShop(HttpServletRequest request, @RequestBody Shop shop) {

        String token = request.getHeader("tokenMiniAPP");

        JWTVerifier build = JWT.require(Algorithm.HMAC256("userInfo")).build();
        DecodedJWT verify = build.verify(token);

        String userId = verify.getClaim("userId").asString();

        Createuuid createuuid = new Createuuid();
        String uuid = createuuid.getOrderIdByUUId();

        shop.setOwnerId(userId);
        shop.setShopId(uuid);

        shopService.applyNewShop(shop);

        Response response = new Response("10000", "成功", "申请成功,请等待管理员审批");
        return response;
    }


    /**
     * 管理员相关接口
     */

    /**
     * 根据条件获取所有商店
     */
    @ResponseBody
    @RequestMapping(value = "/searchAllShop", method = RequestMethod.POST,produces = "application/json;charset=UTF-8")
    private Response searchAllShop(@RequestBody SearchCondition searchCondition) {


        searchCondition.setData(shopService.searchAllShop(searchCondition));
        searchCondition.setTotal(shopService.searchAllShopCount(searchCondition));


        Response response = new Response("10000", "成功", searchCondition);
        return response;
    }

    /**
     * 下架商店
     */
    @ResponseBody
    @RequestMapping(value = "/suspendTheShop", method = RequestMethod.POST,produces = "application/json;charset=UTF-8")
    private Response suspendTheShop(HttpServletRequest request, @RequestBody Shop shop) throws IOException {
        String token = request.getHeader("tokenMiniAPP");

        JWTVerifier build = JWT.require(Algorithm.HMAC256("userInfo")).build();
        DecodedJWT verify = build.verify(token);

        String userId = verify.getClaim("userId").asString();

        Notice notice = new Notice();

        Createuuid createuuid = new Createuuid();
        String uuid = createuuid.getOrderIdByUUId();
        notice.setNoticeId(uuid);

        GetTime getTime = new GetTime();
        String createTime = getTime.getNowTime();
        notice.setCreateTime(createTime);

        User user = new User();
        user.setUserId(userId);
        User performer = userService.findShopOwner(user);
        notice.setPerformerId(userId);
        notice.setPerformerName(performer.getUserName());

        Shop shop1 = shopService.searchOneShop(shop);

        notice.setPassiveId(shop1.getShopId());
        notice.setPassiveName(shop1.getShopName());
        notice.setShopId(shop1.getShopId());
        notice.setType(2);

        shopService.suspendTheShop(shop);
        noticeService.addNotice(notice);
        WebSocketServer.sendInfo("有新通知,请查看", shop1.getShopId());

        Response response = new Response("10000", "成功", "成功");
        return response;
    }

    /**
     * 上架商店
     */
    @ResponseBody
    @RequestMapping(value = "/continueTheShop", method = RequestMethod.POST,produces = "application/json;charset=UTF-8")
    private Response continueTheShop(HttpServletRequest request, @RequestBody Shop shop) throws IOException {

        String token = request.getHeader("tokenMiniAPP");

        JWTVerifier build = JWT.require(Algorithm.HMAC256("userInfo")).build();
        DecodedJWT verify = build.verify(token);

        String userId = verify.getClaim("userId").asString();

        Notice notice = new Notice();

        Createuuid createuuid = new Createuuid();
        String uuid = createuuid.getOrderIdByUUId();
        notice.setNoticeId(uuid);

        GetTime getTime = new GetTime();
        String createTime = getTime.getNowTime();
        notice.setCreateTime(createTime);

        User user = new User();
        user.setUserId(userId);
        User performer = userService.findShopOwner(user);
        notice.setPerformerId(userId);
        notice.setPerformerName(performer.getUserName());

        Shop shop1 = shopService.searchOneShop(shop);

        notice.setPassiveId(shop1.getShopId());
        notice.setPassiveName(shop1.getShopName());
        notice.setShopId(shop1.getShopId());
        notice.setType(2);

        shopService.continueTheShop(shop);
        noticeService.addNotice(notice);
        WebSocketServer.sendInfo("有新通知,请查看", shop1.getShopId());

        Response response = new Response("10000", "成功", "成功");
        return response;
    }

    /**
     * 管理员根据ownerId获取其拥有的商店
     */
    @ResponseBody
    @RequestMapping(value = "/managerShopOwnerSearch", method = RequestMethod.POST,produces = "application/json;charset=UTF-8")
    private Response managerShopOwnerSearch(@RequestBody Shop shop) throws JsonProcessingException {
        List<Shop> shopList = shopService.shopOwnerSearch(shop);
        Response response = new Response("10000", "成功", shopList);
        return response;
    }

    /**
     * 管理员修改商店的具体信息
     */
    @ResponseBody
    @RequestMapping(value = "/managerUpdateShopInfo", method = RequestMethod.POST,produces = "application/json;charset=UTF-8")
    private Response managerUpdateShopInfo(HttpServletRequest request, @RequestBody Shop shop) throws IOException {

        String token = request.getHeader("tokenMiniAPP");

        JWTVerifier build = JWT.require(Algorithm.HMAC256("userInfo")).build();
        DecodedJWT verify = build.verify(token);

        String userId = verify.getClaim("userId").asString();

        Shop shop1 = shopService.searchOneShop(shop);

        if(!Objects.equals(shop1.getShopName(), shop.getShopName()) || !Objects.equals(shop1.getBackCateName(), shop.getBackCateName())
                || !Objects.equals(shop1.getShopPhone(), shop.getShopPhone()) || !Objects.equals(shop1.getFrontImgUrl(), shop.getFrontImgUrl())
                || !Objects.equals(shop1.getShopAddress(), shop.getShopAddress())
        ) {
            Notice notice = new Notice();

            Createuuid createuuid = new Createuuid();
            String uuid = createuuid.getOrderIdByUUId();
            notice.setNoticeId(uuid);

            GetTime getTime = new GetTime();
            String createTime = getTime.getNowTime();
            notice.setCreateTime(createTime);

            User user = new User();
            user.setUserId(userId);
            User performer = userService.findShopOwner(user);
            notice.setPerformerId(userId);
            notice.setPerformerName(performer.getUserName());

            notice.setPassiveId(shop1.getShopId());
            notice.setPassiveName(shop1.getShopName());
            notice.setShopId(shop1.getShopId());
            notice.setType(1);

            shopService.updateShopInfo(shop);
            noticeService.addNotice(notice);
            WebSocketServer.sendInfo("有新通知,请查看", shop1.getShopId());

            Response response = new Response("10000", "成功", "修改成功");
            return response;
        }

        Response response = new Response("10000", "成功", "成功");
        return response;
    }
}

